// Raf Lempens & Bjorn Schobben
#include "Robot.h"
#include "MoveAbility.h"
#include "TurnAbility.h"
#include "HitAbility.h"
#include <stdio.h>

Robot::Robot(const std::string& type, unsigned int initialCellX, unsigned int initialCellY): GameObject(initialCellX, initialCellY), robotType(type), moveAbility(0), turnAbility(0), hitAbility(0), checkpointreachedAbility(0), repairpointreachedAbility(0), dropAbility(0), currentBehavior(0)
{
	moveAbility = new MoveAbility(this);
	turnAbility = new TurnAbility(this);
	hitAbility = new HitAbility(this);
	checkpointreachedAbility = new CheckpointReachedAbility(this);
	repairpointreachedAbility = new RepairpointReachedAbility(this);
	dropAbility = new DropAbility(this);


	AddAbility(moveAbility);
	AddAbility(turnAbility);
	AddAbility(hitAbility);
	AddAbility(checkpointreachedAbility);
	AddAbility(repairpointreachedAbility);
	AddAbility(dropAbility);

	damage = 0;
	lives = 3;
	gameover = false;
}

Robot::~Robot()
{
	if (moveAbility)
	{
		delete moveAbility;
		moveAbility = 0;
	}

	if (turnAbility)
	{
		delete turnAbility;
		turnAbility = 0;
	}

	if (hitAbility)
	{
		delete hitAbility;
		hitAbility = 0;
	}

	if (checkpointreachedAbility)
	{
		delete checkpointreachedAbility;
		checkpointreachedAbility = 0;
	}

	if (repairpointreachedAbility)
	{
		delete repairpointreachedAbility;
		repairpointreachedAbility = 0;
	}

	if (dropAbility)
	{
		delete dropAbility;
		dropAbility = 0;
	}
}


void Robot::MoveLeft()
{
	printf("Robot moving left\n");
	SetPosition(CellX()-1, CellY());
}

void Robot::MoveRight()
{
	printf("Robot moving right\n");
	SetPosition(CellX()+1, CellY());
}

void Robot::MoveUp()
{
	printf("Robot moving up\n");
	SetPosition(CellX(), CellY()-1);
}

void Robot::MoveDown()
{
	printf("Robot moving down\n");
	SetPosition(CellX(), CellY()+1);
}

void Robot::TurnLeft()
{
	switch (direction.Type())
	{
		case Direction::NORTH:
			direction = Direction::WEST;
		break;
		case Direction::WEST:
			direction = Direction::SOUTH;
		break;
		case Direction::SOUTH:
			direction = Direction::EAST;
		break;
		case Direction::EAST:
			direction = Direction::NORTH;
		break;
	}

	printf("Robot turning left (direction is %s)\n", direction.ToString().c_str());
}

void Robot::TurnRight()
{
	switch (direction.Type())
	{
		case Direction::NORTH:
			direction = Direction::EAST;
		break;
		case Direction::EAST:
			direction = Direction::SOUTH;
		break;
		case Direction::SOUTH:
			direction = Direction::WEST;
		break;
		case Direction::WEST:
			direction = Direction::NORTH;
		break;
	}

	printf("Robot turning right (direction is %s)\n", direction.ToString().c_str());
}

void Robot::Hit()
{
	if (gameover)
		return;

	damage++;
	if (damage >= 9)
	{
		damage = 0;

		Die();
	}
	else
	{
		printf("Robot hit! damage is %d\n", damage);
	}
}

void Robot::Die()
{
	if (lives)
	{
		lives--;
		
		if (lives == 0)
		{
			printf("Robot is gameover!\n");
			gameover = true;
		}
		else
		{
			printf("Robot died! lives is %d\n", lives);
		}
	}
}

void Robot::CheckpointReached()
{
	printf("Checkpoint Reached!\n");
}

void Robot::RepairpointReached()
{
	if (damage)
	{
		damage--;
		printf("Robot reached repairpoint! damage is %d\n", damage);
	}
}

void Robot::Drop()
{
	printf("Robot Dropped!\n");

	Die();
}


GameBehavior* Robot::GetBehavior()
{
	return currentBehavior;
}

void Robot::BehaviorFinished()
{
	currentBehavior = 0;
}

void Robot::ScheduleMoveUp()
{
	moveBehavior.SetInitialObject(this, Direction::NORTH);
	currentBehavior = &moveBehavior;
}

void Robot::ScheduleMoveLeft()
{
	moveBehavior.SetInitialObject(this, Direction::WEST);
	currentBehavior = &moveBehavior;
}

void Robot::ScheduleMoveDown()
{
	moveBehavior.SetInitialObject(this, Direction::SOUTH);
	currentBehavior = &moveBehavior;
}

void Robot::ScheduleMoveRight()
{
	moveBehavior.SetInitialObject(this, Direction::EAST);
	currentBehavior = &moveBehavior;
}